package com.yafeng.logic.controller;

import com.yafeng.comonutils.ApiResult;
import com.yafeng.logic.vo.QueryUserInfo;
import com.yafeng.logic.entity.UserOprator;
import com.yafeng.logic.service.UserOperatorService;
import com.yafeng.logic.vo.SetRoleVo;
import com.yafeng.utils.CollectionUtils;
import com.yafeng.utils.RedisUtils;
import com.yafeng.utils.UserToken;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author cn.classbao
 * @since 2020-08-04
 */
@Slf4j
@RestController
@RequestMapping("/user-operator")
@CrossOrigin
public class UserOperatorController {

    @Autowired
    private UserOperatorService userOperatorService;
    @Autowired
    private RedisUtils redisUtils;

    @PostMapping("login")
    @ApiOperation("登录获取Token")
    public ApiResult login(@RequestBody UserOprator userOperator,
                           HttpServletRequest request,
                           HttpServletResponse response) {

        String token = CollectionUtils.getTokenByCookie(request, response); //cookie中获取token
        if(token!=null) return ApiResult.error().code(20001).data("msg","你已经登录");

        Subject subject = SecurityUtils.getSubject();
        UserOprator user=null;

        try {

            //将用户请求参数封装后，直接提交给Shiro处理
            subject.login(new UserToken(userOperator.getUsername(), userOperator.getPassword(), "Login"));

            //Shiro认证通过后会将user信息放到subject内，生成token并返回
            user= (UserOprator) subject.getPrincipal();
            String newToken = userOperatorService.generateJwtToken(user.getUsername(),redisUtils.expirationSeconds); //给客户端的 5分钟过期
            String access_token = userOperatorService.generateJwtToken(user.getUsername(),redisUtils.validTime); //验证过期  7天


            try {

                //生成cookie
                userOperatorService.generateTokenCookie(response,newToken);

                //保存redis中
                redisUtils.set(newToken,access_token, redisUtils.validTime);

                long time = redisUtils.getTime(newToken);
                log.info("redis过期时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis() + time)));

            } catch (Exception e) {

                log.info("redis存入发生异常");
                return ApiResult.error().code(20001);
            }

            return ApiResult.ok().code(20000).data("token",newToken);


        } catch (AuthenticationException e) {

            // 如果校验失败，shiro会抛出异常，返回客户端失败
            return ApiResult.error().code(20001).data("msg","发生异常");
        }


    }
    @GetMapping("userInfo")
    @ApiOperation("拉取用户信息进入首页")
    public ApiResult userInfo(){

        List<UserOprator> list = userOperatorService.list(null);
        return ApiResult
                .ok()
                .data("roles","[admin,orr]")
                .data("avatar","https://dss3.baidu.com/-rVXeDTa2gU2pMbgoY3K/it/u=777413989,2120728914&fm=202&mola=new&crop=v1")
                .data("name","baoyanpei");

    }

    @GetMapping("query-user-list")
    @ApiOperation("查询用户信息列表")
    public ApiResult userQueryList(QueryUserInfo queryUserInfo){

        return userOperatorService.userQueryList(queryUserInfo);
    }

    @PostMapping("logout")
    @ApiOperation("用户退出")
    public ApiResult logout(HttpServletRequest request){

        //删除redis中的值
        redisUtils.delete(request.getHeader("token"));
        return ApiResult.ok();

    }
    @PostMapping("to-user-set-role")
    @ApiOperation("通过用户设置角色")
    @Transactional
    public ApiResult toUserSetRole(@RequestBody SetRoleVo setRoleVo){


        try {
           return  userOperatorService.toUserSetRole(setRoleVo);
        } catch (Exception e) {
             e.printStackTrace();
            throw new RuntimeException();
        }


    }



}

